﻿using System.IO;

namespace NFox.Pycad
{
    public class Module
    {

        public virtual int Level { get { return 1; } }

        public dynamic Tag { get; set; }

        public IDocument Document { get; set; }

        public virtual void CloseDocument()
        {
            Document?.Close();
        }

        public delegate void ModuleEventHandle(Module module, ModuleEventArgs e);
        public delegate void ModuleItemsEventHandle(Package package, ModuleItemsEventArgs e);

        public ModuleEventHandle ModuleChanged;
        public ModuleItemsEventHandle ModuleItemsChanged;

        #region Edit

        public virtual void Rename(string name)
        {
            File.MoveTo(Parent.Directory.FullName + "\\" + name);
            Parent.RemoveModule(this, false);
            Name = name;
            ModuleChanged?.Invoke(this, new ModuleEventArgs("Name"));
            Parent.Add(this);
        }

        public virtual void Remove()
        {
            CloseDocument();
            Parent.RemoveModule(this, true);
        }

        public static bool Over { get; set; }

        public virtual bool CopyTo(Package parent)
        {
            var m = parent.GetModule(Name);
            if (m == null)
            {
                var file = File.CopyTo(parent.Directory.FullName + "\\" + File.Name);
                m = new Module(Name);
                parent.Add(m);
                return true;
            }
            else if (Over)
            {
                CloseDocument();
                File.CopyTo(parent.Directory.FullName + "\\" + File.Name, true);
                return true;
            }
            return false;
        }

        #endregion

        public Package Parent { get; set; }

        public string Name { get; set; }

        public virtual string FullName
        {
            get { return $"{Parent.FullName}.{Name.Substring(0, Name.Length - 3)}"; }
        }

        public virtual FileInfo File
        {
            get { return new FileInfo(Path); }
        }

        protected string _path;

        public virtual string Path
        {
            get { return _path ?? $"{Parent.Path}\\{Name}"; }
        }

        public bool IsRoot { get { return this == PluginBase.Engine.Projects; } }

        public virtual bool IsModule { get { return true; } }

        public virtual bool IsPackage { get { return false; } }

        public virtual bool IsProject { get { return false; } }

        private bool _visible;
        public bool Visible
        {
            get { return _visible; }
            set
            {
                _visible = value;
                ModuleChanged?.Invoke(this, new ModuleEventArgs("Visible"));
            }
        }

        public bool IsSystem { get; set; }

        public Module(string name)
        {
            Name = name;
            Visible = true;
            IsSystem = false;
        }

        public static Module FromFile(string path)
        {
            string name = System.IO.Path.GetFileNameWithoutExtension(path);
            Module m = new Module(name);
            m._path = path;
            return m;
        }

        public bool IsPartOf(Module other)
        {
            if (other is Package)
            {
                var p = this;
                while (p != null)
                {
                    if (p == other)
                        return true;
                    p = p.Parent;
                }
            }
            return false;
        }

        public bool IsSubOf(Module other)
        {
            return Parent == other;
        }

        public override string ToString()
        {
            return $"Module:({Path})";
        }

    }
}
